package org.easy.excel.support;

import com.alibaba.excel.write.handler.WriteHandler;
import org.easy.excel.support.config.ExcelConfig;
import org.easy.excel.support.config.entity.ExportStreamSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.List;

import static org.easy.excel.support.WebExcelExportService.WebExcelExportSupport.*;

/**
 * Web 导出 Excel 文件
 *
 * @author 李坤
 * @date 2022/4/25 20:07
 */
@Service
public class WebExcelExportService implements ExcelExportService {

    private final Logger logger = LoggerFactory.getLogger(ExcelExportService.class);

    /**
     * 通过 HttpServletResponse 导出Excel
     *
     * @param servletResponse HttpServletResponse
     * @param dataList        数据
     * @param excelConfig     导出配置
     */
    public void export4ServletResponse(HttpServletResponse servletResponse, ExcelConfig excelConfig) {
        // 设置导出文件头信息
        setServletResponseHeader(servletResponse, excelConfig.getFileName());

        try {
            export(servletResponse.getOutputStream(), excelConfig);
        } catch (IOException exception) {
            logger.error("导出数据失败", exception);
        }
    }

    /**
     * 通过 HttpServletResponse 导出Excel
     *
     * @param servletResponse HttpServletResponse
     * @param excelHeads      Excel标题
     * @param writeHandlers   Excel处理拦截器
     * @param filename        文件名称
     * @param sheetName       SheetName
     */
    public ExportStreamSupport getExportStreamSupport4Servlet(HttpServletResponse servletResponse, List<List<String>> excelHeads,
                                                              Collection<WriteHandler> writeHandlers, String filename, String sheetName) {
        // 设置导出文件头信息
        setServletResponseHeader(servletResponse, filename);

        try {
            return getExportStreamSupport(servletResponse.getOutputStream(), excelHeads, writeHandlers, sheetName);
        } catch (IOException exception) {
            logger.error("导出数据失败", exception);
        }
        return null;
    }

    /**
     * 设置response的返回头信息
     *
     * @param response response
     * @param fileName 导出文件的名称
     */
    protected void setServletResponseHeader(HttpServletResponse response, String fileName) {
        try {
            response.setContentType(CONTENT_TYPE);
            response.addHeader(HEADER_KEY_CACHE, NO_CACHE);
            response.addHeader(HEADER_KEY_PARGAM, NO_CACHE);
            response.addHeader(ACCESS_CONTROL_EXPOSE_HEADERS, HEADER_KEY_DISPOSITION);
            response.setHeader(HEADER_KEY_DISPOSITION, HEADER_VALUE_DISPOSITION.replace(PLACEHOLDER, URLEncoder.encode(fileName, ENCODE)));
        } catch (UnsupportedEncodingException exception) {
            logger.error("设置response的返回头信息失败", exception);
        }
    }


    /*------------------------------------------------public interface------------------------------------------------*/


    public interface WebExcelExportSupport {
        String ENCODE = "UTF-8";
        String PLACEHOLDER = "{0}";
        String NO_CACHE = "no-cache";
        String HEADER_KEY_PARGAM = "Pargam";
        String HEADER_KEY_CACHE = "Cache-Control";
        String DATA_EMPTY = "导出数据为空，请重新选择";
        String HEADER_KEY_DISPOSITION = "Content-Disposition";
        String HEADER_VALUE_DISPOSITION = "attachment;filename={0}.xlsx";
        String CONTENT_TYPE = "application/octet-stream;charset=ISO8859-1";
        String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
    }

}
